package cn.edu.sgu.www.pms.shiro.filter;

import cn.edu.sgu.www.pms.restful.JsonResult;
import cn.edu.sgu.www.pms.restful.ResponseCode;
import cn.edu.sgu.www.pms.util.HeaderMatcher;
import cn.edu.sgu.www.pms.util.HttpUtils;
import cn.edu.sgu.www.pms.util.StringUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 定义PermsFilter过滤器（覆盖shiro的perms过滤器）
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Slf4j
public class PermsFilter extends PermissionsAuthorizationFilter {

    /**
     * 本项目的RPC接口URL列表
     */
    private final List<String> remoteUrls;

    public PermsFilter(List<String> remoteUrls) {
        this.remoteUrls = remoteUrls;
    }

    @Override
    public boolean isAccessAllowed(ServletRequest req, ServletResponse resp, Object mappedValue) throws IOException {
        HttpServletRequest request = (HttpServletRequest) req;

        // 得到RPC请求头名称
        String headerName = HeaderMatcher.getHeaderName();
        // 从请求中获取请求头
        String header = request.getHeader(headerName);
        // 得到请求地址
        String requestURI = request.getRequestURI();

        if (StringUtils.isNotEmpty(header)) {
            log.debug("发现请求头{}", headerName);

            // RPC接口才跳过鉴权
            if (HeaderMatcher.match(header) && remoteUrls.contains(requestURI)) {
                log.debug("当前请求为授权应用发起的请求，跳过鉴权~");

                return true;
            }
        }

        boolean accessAllowed = super.isAccessAllowed(req, resp, mappedValue);

        // 未授权的处理
        if (!accessAllowed) {
            log.debug("正在访问未授权的资源：{}", requestURI);

            // 得到未授权状态码
            ResponseCode responseCode = ResponseCode.UNAUTHORIZED;
            // 构建返回对象
            JsonResult<Void> jsonResult = JsonResult.error(responseCode, "正在访问未授权的资源：" + requestURI);

            // 获取HttpServletResponse对象
            HttpServletResponse response = HttpUtils.getResponse();

            response.reset();
            response.setStatus(responseCode.getValue());
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(JSON.toJSONString(jsonResult));
        }

        return true;
    }

}